# 舆论情绪、政策和事件对汇率影响分析
import os
import json
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.dates as mdates
from datetime import datetime, timedelta
import re
from collections import Counter
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression

# 设置中文字体
# 尝试使用多种中文字体，以提高兼容性
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体
plt.rcParams['axes.unicode_minus'] = False   # 解决负号显示问题

# 创建输出目录
output_dir = "output_images"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
    print(f"创建目录: {output_dir}")

# 与汇率预测模块集成的接口函数
def integrate_with_exchange_rate_prediction(currency_pair='USD/CNY', exchange_rate_data=None, predicted_rate=None, start_date=None, end_date=None):
    """与汇率预测模块集成的接口函数
    
    参数:
        currency_pair: 货币对名称，如'USD/CNY'
        exchange_rate_data: 汇率历史数据
        predicted_rate: 预测的汇率数据
        start_date: 开始日期
        end_date: 结束日期
        
    返回:
        分析结果字典
    """
    # 调用主函数进行分析
    results = main(currency_pair, start_date, end_date, exchange_rate_data, predicted_rate)
    return results

# 生成舆论情绪数据（支持真实数据和模拟数据）
def generate_sentiment_data(start_date='2023-01-01', end_date='2023-12-31', use_real_data=True):
    # 尝试使用真实数据
    if use_real_data:
        try:
            # 尝试从网络获取新闻情绪数据
            print("尝试获取真实舆论情绪数据...")
            
            # 检查是否存在本地缓存的情绪数据
            sentiment_file = 'sentiment_data.csv'
            if os.path.exists(sentiment_file):
                print(f"读取本地情绪数据: {sentiment_file}")
                sentiment_df = pd.read_csv(sentiment_file)
                sentiment_df['date'] = pd.to_datetime(sentiment_df['date'])
                sentiment_df.set_index('date', inplace=True)
                
                # 过滤日期范围
                start = pd.to_datetime(start_date)
                end = pd.to_datetime(end_date)
                sentiment_df = sentiment_df[(sentiment_df.index >= start) & (sentiment_df.index <= end)]
                
                if not sentiment_df.empty:
                    print(f"成功加载真实情绪数据，共{len(sentiment_df)}条记录")
                    return sentiment_df
            
            # 如果没有本地数据或数据为空，则回退到模拟数据
            print("未找到真实情绪数据，使用模拟数据代替")
        except Exception as e:
            print(f"加载真实情绪数据失败: {str(e)}，使用模拟数据代替")
    
    # 使用模拟数据
    print("生成模拟舆论情绪数据...")
    date_range = pd.date_range(start=start_date, end=end_date)
    
    # 基础情绪值
    base_sentiment = np.linspace(0.5, 0.7, len(date_range))
    
    # 添加随机波动
    random_fluctuation = np.random.normal(0, 0.1, len(date_range))
    
    # 添加特定事件影响
    events = {
        '2023-03-15': -0.2,  # 负面事件
        '2023-05-20': 0.25,   # 正面事件
        '2023-07-10': -0.15,  # 负面事件
        '2023-09-05': 0.2,    # 正面事件
        '2023-11-25': -0.25   # 负面事件
    }
    
    sentiment = base_sentiment + random_fluctuation
    
    # 应用事件影响
    for date_str, impact in events.items():
        event_date = pd.to_datetime(date_str)
        if event_date in date_range:
            idx = date_range.get_loc(event_date)
            
            # 事件影响会在一段时间内逐渐消退
            decay_period = 14  # 影响持续14天
            for i in range(decay_period):
                if idx + i < len(sentiment):
                    decay_factor = (decay_period - i) / decay_period
                    sentiment[idx + i] += impact * decay_factor
    
    # 确保情绪值在[0, 1]范围内
    sentiment = np.clip(sentiment, 0, 1)
    
    # 创建DataFrame
    sentiment_df = pd.DataFrame({
        'date': date_range,
        'sentiment': sentiment
    })
    sentiment_df.set_index('date', inplace=True)
    
    return sentiment_df

# 生成政策数据（支持真实数据和模拟数据）
def generate_policy_data(start_date='2023-01-01', end_date='2023-12-31', use_real_data=True):
    # 尝试使用真实数据
    if use_real_data:
        try:
            # 检查是否存在本地缓存的政策数据
            policy_file = 'D:/13langgraph/policy_data.csv'
            policy_events_file = 'policy_events.json'
            
            if os.path.exists(policy_file) and os.path.exists(policy_events_file):
                print(f"读取本地政策数据: {policy_file}")
                policy_df = pd.read_csv(policy_file)
                policy_df['date'] = pd.to_datetime(policy_df['date'])
                policy_df.set_index('date', inplace=True)
                
                # 读取政策事件数据
                import json
                with open(policy_events_file, 'r', encoding='utf-8') as f:
                    policies = json.load(f)
                
                # 过滤日期范围
                start = pd.to_datetime(start_date)
                end = pd.to_datetime(end_date)
                policy_df = policy_df[(policy_df.index >= start) & (policy_df.index <= end)]
                
                if not policy_df.empty:
                    print(f"成功加载真实政策数据，共{len(policy_df)}条记录")
                    return policy_df, policies
            
            # 如果没有本地数据或数据为空，则回退到模拟数据
            print("未找到真实政策数据，使用模拟数据代替")
        except Exception as e:
            print(f"加载真实政策数据失败: {str(e)}，使用模拟数据代替")
    
    # 使用模拟数据
    print("生成模拟政策数据...")
    date_range = pd.date_range(start=start_date, end=end_date)
    
    # 创建政策影响数据
    policy_impact = np.zeros(len(date_range))
    
    # 添加政策事件
    policies = {
        '2023-02-10': {'name': '央行降准', 'impact': 0.15, 'duration': 30, 'description': '中国人民银行下调金融机构存款准备金率0.5个百分点'},
        '2023-04-25': {'name': '外汇管理新规', 'impact': -0.1, 'duration': 45, 'description': '国家外汇管理局发布跨境资金流动管理新规定'},
        '2023-06-15': {'name': '利率调整', 'impact': 0.2, 'duration': 60, 'description': '中国人民银行调整贷款市场报价利率(LPR)'},
        '2023-08-20': {'name': '跨境贸易政策', 'impact': 0.1, 'duration': 40, 'description': '商务部发布促进跨境贸易便利化新措施'},
        '2023-10-05': {'name': '金融市场开放措施', 'impact': 0.25, 'duration': 50, 'description': '金融监管部门发布一系列金融市场对外开放新政策'},
        '2023-12-01': {'name': '年末流动性调节', 'impact': -0.05, 'duration': 30, 'description': '央行开展年末流动性调节操作'}
    }
    
    # 应用政策影响
    for date_str, policy in policies.items():
        policy_date = pd.to_datetime(date_str)
        if policy_date in date_range:
            idx = date_range.get_loc(policy_date)
            duration = policy['duration']
            impact = policy['impact']
            
            # 政策影响会在一段时间内逐渐变化
            for i in range(duration):
                if idx + i < len(policy_impact):
                    # 政策影响先增强后减弱
                    if i < duration / 3:
                        factor = i / (duration / 3)
                    else:
                        factor = (duration - i) / (duration * 2/3)
                    policy_impact[idx + i] += impact * factor
    
    # 创建DataFrame
    policy_df = pd.DataFrame({
        'date': date_range,
        'policy_impact': policy_impact
    })
    policy_df.set_index('date', inplace=True)
    
    # 保存模拟数据到本地（可选）
    try:
        policy_df.reset_index().to_csv('policy_data.csv', index=False)
        import json
        with open('policy_events.json', 'w', encoding='utf-8') as f:
            json.dump(policies, f, ensure_ascii=False, indent=4)
        print("模拟政策数据已保存到本地，下次可直接加载")
    except Exception as e:
        print(f"保存模拟政策数据失败: {str(e)}")
    
    return policy_df, policies

# 生成重大事件数据（支持真实数据和模拟数据）
def generate_event_data(start_date='2023-01-01', end_date='2023-12-31', use_real_data=True):
    # 尝试使用真实数据
    if use_real_data:
        try:
            # 检查是否存在本地缓存的事件数据
            event_file = 'D:/13langgraph/event_data.csv'
            event_details_file = 'event_details.json'
            
            if os.path.exists(event_file) and os.path.exists(event_details_file):
                print(f"读取本地事件数据: {event_file}")
                event_df = pd.read_csv(event_file)
                event_df['date'] = pd.to_datetime(event_df['date'])
                event_df.set_index('date', inplace=True)
                
                # 读取事件详情数据
                import json
                with open(event_details_file, 'r', encoding='utf-8') as f:
                    events = json.load(f)
                
                # 过滤日期范围
                start = pd.to_datetime(start_date)
                end = pd.to_datetime(end_date)
                event_df = event_df[(event_df.index >= start) & (event_df.index <= end)]
                
                if not event_df.empty:
                    print(f"成功加载真实事件数据，共{len(event_df)}条记录")
                    return event_df, events
            
            # 如果没有本地数据或数据为空，则回退到模拟数据
            print("未找到真实事件数据，使用模拟数据代替")
        except Exception as e:
            print(f"加载真实事件数据失败: {str(e)}，使用模拟数据代替")
    
    # 使用模拟数据
    print("生成模拟重大事件数据...")
    date_range = pd.date_range(start=start_date, end=end_date)
    
    # 创建事件影响数据
    event_impact = np.zeros(len(date_range))
    
    # 添加重大事件
    events = {
        '2023-01-20': {'name': '国际贸易摩擦', 'impact': -0.3, 'duration': 20, 'description': '主要经济体之间贸易关系紧张，可能导致关税上调'},
        '2023-03-05': {'name': '全球金融市场波动', 'impact': -0.25, 'duration': 15, 'description': '全球股市大幅波动，避险情绪上升'},
        '2023-05-10': {'name': '主要经济体数据公布', 'impact': 0.2, 'duration': 10, 'description': '美国、欧盟等主要经济体公布经济数据好于预期'},
        '2023-07-15': {'name': '地缘政治冲突', 'impact': -0.35, 'duration': 25, 'description': '国际地缘政治局势紧张，影响全球金融市场稳定'},
        '2023-09-25': {'name': '国际评级调整', 'impact': 0.15, 'duration': 12, 'description': '国际评级机构上调中国主权信用评级'},
        '2023-11-10': {'name': '全球央行政策协调', 'impact': 0.3, 'duration': 18, 'description': '主要经济体央行协调货币政策，稳定全球金融市场'}
    }
    
    # 应用事件影响
    for date_str, event in events.items():
        event_date = pd.to_datetime(date_str)
        if event_date in date_range:
            idx = date_range.get_loc(event_date)
            duration = event['duration']
            impact = event['impact']
            
            # 事件影响通常是突然的，然后逐渐减弱
            for i in range(duration):
                if idx + i < len(event_impact):
                    decay_factor = (duration - i) / duration
                    event_impact[idx + i] += impact * decay_factor
    
    # 创建DataFrame
    event_df = pd.DataFrame({
        'date': date_range,
        'event_impact': event_impact
    })
    event_df.set_index('date', inplace=True)
    
    # 保存模拟数据到本地（可选）
    try:
        event_df.reset_index().to_csv('event_data.csv', index=False)
        import json
        with open('event_details.json', 'w', encoding='utf-8') as f:
            json.dump(events, f, ensure_ascii=False, indent=4)
        print("模拟事件数据已保存到本地，下次可直接加载")
    except Exception as e:
        print(f"保存模拟事件数据失败: {str(e)}")
    
    return event_df, events

# 生成汇率数据（支持真实数据和模拟数据）
def generate_exchange_rate_data(sentiment_df, policy_df, event_df, start_date='2023-01-01', end_date='2023-12-31', currency_pair='USD/CNY', use_real_data=True):
    # 尝试使用真实数据
    if use_real_data:
        try:
            # 根据货币对选择对应的CSV文件
            if currency_pair == 'USD/CNY':
                file_path = 'usd_cny.csv'
            elif currency_pair == 'EUR/USD':
                file_path = 'eur_usd.csv'
            else:  # 默认 EUR/CNY
                file_path = 'eur_cny.csv'
                currency_pair = 'EUR/CNY'
            
            # 检查文件是否存在
            if os.path.exists(file_path):
                print(f"读取真实汇率数据: {file_path}")
                
                # 读取CSV文件，跳过前三行元数据
                try:
                    # 首先尝试读取文件的前几行来检查格式
                    header_check = pd.read_csv(file_path, nrows=5)
                    
                    # 检查是否包含元数据行
                    if 'Ticker' in str(header_check.iloc[0:3].values):
                        print(f"检测到{file_path}包含元数据行，跳过前三行")
                        df = pd.read_csv(file_path, skiprows=3)
                    else:
                        df = pd.read_csv(file_path)
                except Exception as read_error:
                    print(f"读取文件时出错，尝试使用更宽松的解析方式: {read_error}")
                    df = pd.read_csv(file_path, skiprows=3, header=None)
                
                # 确保数据格式正确
                if len(df.columns) >= 2:
                    # 重命名列
                    df.columns = ['Date', 'exchange_rate'] if len(df.columns) == 2 else ['Date', 'exchange_rate'] + [f'Col_{i}' for i in range(len(df.columns)-2)]
                    
                    # 删除可能的空行
                    df = df.dropna(subset=['Date', 'Exchange_Rate'])
                    
                    # 转换日期列为日期类型
                    df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
                    # 删除无效日期
                    df = df.dropna(subset=['Date'])
                    
                    # 过滤日期范围
                    start = pd.to_datetime(start_date)
                    end = pd.to_datetime(end_date)
                    df = df[(df['Date'] >= start) & (df['Date'] <= end)]
                    
                    # 设置日期为索引
                    df.set_index('Date', inplace=True)
                    
                    # 确保汇率列为数值类型
                    df['exchange_rate'] = pd.to_numeric(df['exchange_rate'], errors='coerce')
                    
                    # 按时间升序排列，从旧到新
                    df = df.sort_index(ascending=True)
                    
                    # 处理缺失值
                    if df['exchange_rate'].isnull().any():
                        missing_count = df['exchange_rate'].isnull().sum()
                        print(f"警告：{file_path}中存在{missing_count}个缺失值，使用前值填充")
                        df['exchange_rate'] = df['exchange_rate'].fillna(method='ffill')
                        # 如果仍有缺失值（例如第一个值），使用后值填充
                        df['exchange_rate'] = df['exchange_rate'].fillna(method='bfill')
                    
                    if not df.empty:
                        print(f"成功加载{currency_pair}真实汇率数据，共{len(df)}条记录")
                        return df
            
            # 如果没有找到文件或数据处理失败，则回退到模拟数据
            print(f"未找到{currency_pair}真实汇率数据文件或处理失败，使用模拟数据代替")
        except Exception as e:
            print(f"加载真实汇率数据失败: {str(e)}，使用模拟数据代替")
    
    # 使用模拟数据
    print("生成模拟汇率数据...")
    date_range = pd.date_range(start=start_date, end=end_date)
    
    # 基础汇率趋势（根据货币对调整初始值）
    if currency_pair == 'USD/CNY':
        base_rate = np.linspace(6.8, 7.2, len(date_range))
    elif currency_pair == 'EUR/USD':
        base_rate = np.linspace(1.05, 1.15, len(date_range))
    else:  # EUR/CNY
        base_rate = np.linspace(7.5, 8.0, len(date_range))
    
    # 添加季节性波动
    seasonal = 0.1 * np.sin(np.linspace(0, 4*np.pi, len(date_range)))
    
    # 添加随机波动
    random_fluctuation = np.random.normal(0, 0.03, len(date_range))
    
    # 计算综合影响
    sentiment_impact = 0.3 * (sentiment_df['sentiment'] - 0.5) * 2  # 将[0,1]映射到[-0.3,0.3]
    policy_impact = 0.5 * policy_df['policy_impact']  # 政策影响权重更大
    event_impact = 0.7 * event_df['event_impact']  # 事件影响权重最大
    
    # 生成汇率
    exchange_rate = base_rate + seasonal + random_fluctuation - sentiment_impact - policy_impact - event_impact
    
    # 创建DataFrame
    exchange_rate_df = pd.DataFrame({
        'date': date_range,
        'exchange_rate': exchange_rate
    })
    exchange_rate_df.set_index('date', inplace=True)
    
    return exchange_rate_df

# 分析舆论情绪、政策和事件对汇率的影响
def analyze_impacts(exchange_rate_df, sentiment_df, policy_df, event_df):
    # 计算相关性
    correlation_sentiment = exchange_rate_df['exchange_rate'].corr(sentiment_df['sentiment'])
    correlation_policy = exchange_rate_df['exchange_rate'].corr(policy_df['policy_impact'])
    correlation_event = exchange_rate_df['exchange_rate'].corr(event_df['event_impact'])
    
    print(f"舆论情绪与汇率相关性: {correlation_sentiment:.4f}")
    print(f"政策影响与汇率相关性: {correlation_policy:.4f}")
    print(f"事件影响与汇率相关性: {correlation_event:.4f}")
    
    # 创建综合数据集
    combined_df = pd.DataFrame({
        'exchange_rate': exchange_rate_df['exchange_rate'],
        'sentiment': sentiment_df['sentiment'],
        'policy_impact': policy_df['policy_impact'],
        'event_impact': event_df['event_impact']
    })
    
    return combined_df

# 可视化结果
def visualize_results(combined_df, policies, events, currency_pair='USD/CNY', analysis_results=None):
 
    
    # 1. 舆论情绪与汇率关系图
    plt.figure(figsize=(15, 7))
    
    # 绘制汇率
    ax1 = plt.gca()
    ax1.plot(combined_df.index, combined_df['exchange_rate'], 'b-', label=f'{currency_pair}汇率')
    
    # 如果有预测数据，也绘制出来
    if 'predicted_rate' in combined_df.columns:
        mask = ~combined_df['predicted_rate'].isna()
        if mask.any():
            ax1.plot(combined_df[mask].index, combined_df.loc[mask, 'predicted_rate'], 'g--', label='预测汇率')
    
    ax1.set_ylabel('汇率', color='b', fontsize=12)
    ax1.tick_params(axis='y', labelcolor='b')
    
    # 设置x轴日期格式和自动调整
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    ax1.xaxis.set_major_locator(mdates.AutoLocator() if hasattr(mdates, 'AutoLocator') else mdates.MonthLocator())
    plt.gcf().autofmt_xdate() # 自动调整日期标签，防止重叠
    
    # 绘制情绪指数
    ax2 = ax1.twinx()
    ax2.plot(combined_df.index, combined_df['sentiment'], 'r-', label='舆论情绪指数')
    ax2.set_ylabel('情绪指数 (0-1)', color='r', fontsize=12)
    ax2.tick_params(axis='y', labelcolor='r')
    
    # 添加标题和图例
    plt.title(f'舆论情绪与{currency_pair}汇率关系分析', fontsize=16)
    lines1, labels1 = ax1.get_legend_handles_labels()
    lines2, labels2 = ax2.get_legend_handles_labels()
    ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')
    
    # 添加相关性信息
    corr = combined_df['exchange_rate'].corr(combined_df['sentiment'])
    plt.figtext(0.15, 0.02, f'相关系数: {corr:.4f}', fontsize=12)
    
    # 如果有高级分析结果，添加贡献度信息
    if analysis_results and 'sentiment_contrib' in analysis_results:
        plt.figtext(0.5, 0.02, f'舆论情绪贡献度: {analysis_results["sentiment_contrib"]:.2%}', fontsize=12)
    
    # 添加网格
    plt.grid(True, linestyle='--', alpha=0.7)
    
    # 保存图表
    sentiment_file = os.path.join(output_dir, f"{currency_pair.replace('/', '_')}_sentiment_analysis.png")
    plt.savefig(sentiment_file, dpi=300, bbox_inches='tight')
    print(f"舆论情绪分析图表已保存为{sentiment_file}")
    plt.close()
    
    # 2. 政策影响与汇率关系图
    plt.figure(figsize=(15, 7))
    
    # 绘制汇率
    ax1 = plt.gca()
    ax1.plot(combined_df.index, combined_df['exchange_rate'], 'b-', label=f'{currency_pair}汇率')
    ax1.set_ylabel('汇率', color='b', fontsize=12)
    ax1.tick_params(axis='y', labelcolor='b')
    
    # 设置x轴日期格式和自动调整
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    ax1.xaxis.set_major_locator(mdates.AutoLocator() if hasattr(mdates, 'AutoLocator') else mdates.MonthLocator())
    plt.gcf().autofmt_xdate()
    
    # 绘制政策影响
    ax2 = ax1.twinx()
    ax2.plot(combined_df.index, combined_df['policy_impact'], 'g-', label='政策影响指数')
    ax2.set_ylabel('政策影响指数', color='g', fontsize=12)
    ax2.tick_params(axis='y', labelcolor='g')
    
    # 标记政策事件
    for date_str, policy in policies.items():
        policy_date = pd.to_datetime(date_str)
        if policy_date in combined_df.index:
            plt.axvline(x=policy_date, color='gray', linestyle='--', alpha=0.7)
            # 添加事件描述（如果有）
            event_text = policy['name']
            if 'description' in policy:
                event_text += f"\n{policy['description'][:30]}..."
            plt.text(policy_date, ax1.get_ylim()[1], event_text, 
                     rotation=90, verticalalignment='top', fontsize=9)
    
    # 添加标题和图例
    plt.title(f'政策事件与{currency_pair}汇率关系分析', fontsize=16)
    lines1, labels1 = ax1.get_legend_handles_labels()
    lines2, labels2 = ax2.get_legend_handles_labels()
    ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')
    
    # 添加相关性信息
    corr = combined_df['exchange_rate'].corr(combined_df['policy_impact'])
    plt.figtext(0.15, 0.02, f'相关系数: {corr:.4f}', fontsize=12)
    
    # 如果有高级分析结果，添加贡献度信息
    if analysis_results and 'policy_contrib' in analysis_results:
        plt.figtext(0.5, 0.02, f'政策影响贡献度: {analysis_results["policy_contrib"]:.2%}', fontsize=12)
    
    # 添加网格
    plt.grid(True, linestyle='--', alpha=0.7)
    
    # 保存图表
    policy_file = os.path.join(output_dir, f"{currency_pair.replace('/', '_')}_policy_analysis.png")
    plt.savefig(policy_file, dpi=300, bbox_inches='tight')
    print(f"政策影响分析图表已保存为{policy_file}")
    plt.close()
    
    # 3. 重大事件与汇率关系图
    plt.figure(figsize=(15, 7))
    
    # 绘制汇率
    ax1 = plt.gca()
    ax1.plot(combined_df.index, combined_df['exchange_rate'], 'b-', label=f'{currency_pair}汇率')
    ax1.set_ylabel('汇率', color='b', fontsize=12)
    ax1.tick_params(axis='y', labelcolor='b')
    
    # 设置x轴日期格式和自动调整
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    ax1.xaxis.set_major_locator(mdates.AutoLocator() if hasattr(mdates, 'AutoLocator') else mdates.MonthLocator())
    plt.gcf().autofmt_xdate()
    
    # 绘制事件影响
    ax2 = ax1.twinx()
    ax2.plot(combined_df.index, combined_df['event_impact'], 'm-', label='事件影响指数')
    ax2.set_ylabel('事件影响指数', color='m', fontsize=12)
    ax2.tick_params(axis='y', labelcolor='m')
    
    # 标记重大事件
    for date_str, event in events.items():
        event_date = pd.to_datetime(date_str)
        if event_date in combined_df.index:
            plt.axvline(x=event_date, color='gray', linestyle='--', alpha=0.7)
            # 添加事件描述（如果有）
            event_text = event['name']
            if 'description' in event:
                event_text += f"\n{event['description'][:30]}..."
            plt.text(event_date, ax1.get_ylim()[1], event_text, 
                     rotation=90, verticalalignment='top', fontsize=9)
    
    # 添加标题和图例
    plt.title(f'重大事件与{currency_pair}汇率关系分析', fontsize=16)
    lines1, labels1 = ax1.get_legend_handles_labels()
    lines2, labels2 = ax2.get_legend_handles_labels()
    ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')
    
    # 添加相关性信息
    corr = combined_df['exchange_rate'].corr(combined_df['event_impact'])
    plt.figtext(0.15, 0.02, f'相关系数: {corr:.4f}', fontsize=12)
    
    # 如果有高级分析结果，添加贡献度信息
    if analysis_results and 'event_contrib' in analysis_results:
        plt.figtext(0.5, 0.02, f'事件影响贡献度: {analysis_results["event_contrib"]:.2%}', fontsize=12)
    
    # 添加网格
    plt.grid(True, linestyle='--', alpha=0.7)
    
    # 保存图表
    event_file = os.path.join(output_dir, f"{currency_pair.replace('/', '_')}_event_analysis.png")
    plt.savefig(event_file, dpi=300, bbox_inches='tight')
    print(f"重大事件分析图表已保存为{event_file}")
    plt.close()
    
    # 4. 综合影响分析图
    if analysis_results and 'sentiment_contrib' in analysis_results:
        plt.figure(figsize=(10, 6))
        
        # 绘制饼图显示各因素贡献度
        labels = ['舆论情绪', '政策影响', '事件影响']
        sizes = [analysis_results['sentiment_contrib'], 
                analysis_results['policy_contrib'], 
                analysis_results['event_contrib']]
        colors = ['#ff9999','#66b3ff','#99ff99']
        explode = (0.1, 0, 0)  # 突出显示第一个扇形
        
        plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%',
                shadow=True, startangle=90)
        plt.axis('equal')  # 确保饼图是圆的
        
        plt.title(f'{currency_pair}汇率影响因素贡献度分析', fontsize=16)
        
        # 添加模型拟合优度信息
        if 'r2' in analysis_results:
            plt.figtext(0.5, 0.03, f'模型拟合优度(R²): {analysis_results["r2"]:.4f}', 
                      ha='center', fontsize=12)
        
        # 保存图表
        contrib_file = os.path.join(output_dir, f"{currency_pair.replace('/', '_')}_factor_contribution.png")
        plt.savefig(contrib_file, dpi=300, bbox_inches='tight')
        print(f"影响因素贡献度分析图表已保存为{contrib_file}")
        plt.close()

# 分析各因素对汇率的贡献度
def analyze_factor_contribution(combined_df):
    """分析各因素对汇率的贡献度"""
    # 准备数据
    X = combined_df[['sentiment', 'policy_impact', 'event_impact']].copy()
    y = combined_df['exchange_rate'].copy()
    
    # 处理缺失值
    X = X.fillna(X.mean())
    y = y.fillna(method='ffill')
    
    # 标准化特征
    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    
    # 使用线性回归模型分析贡献度
    from sklearn.linear_model import LinearRegression
    model = LinearRegression()
    model.fit(X_scaled, y)
    
    # 计算R²
    r2 = model.score(X_scaled, y)
    
    # 计算各因素的贡献度（使用标准化后的系数）
    coefs = np.abs(model.coef_)
    total = np.sum(coefs)
    
    # 如果总和为0，则平均分配贡献度
    if total == 0:
        contrib = np.array([1/3, 1/3, 1/3])
    else:
        contrib = coefs / total
    
    # 返回结果
    return {
        'sentiment_contrib': contrib[0],
        'policy_contrib': contrib[1],
        'event_contrib': contrib[2],
        'r2': r2
    }

# 主函数
def main(currency_pair='USD/CNY', start_date=None, end_date=None, exchange_rate_data=None, predicted_rate=None):
    """主函数，支持与汇率预测模块集成
    
    参数:
        currency_pair: 货币对名称，如'USD/CNY'
        start_date: 开始日期，如果为None则使用默认值
        end_date: 结束日期，如果为None则使用默认值
        exchange_rate_data: 外部传入的汇率数据，如果为None则生成模拟数据
        predicted_rate: 预测的汇率数据，可选
    """
    print("开始分析舆论情绪、政策和事件对汇率的影响...")
    
    # 设置默认日期范围
    if start_date is None:
        start_date = '2023-01-01'
    if end_date is None:
        end_date = '2023-12-31'
    
    # 生成数据
    sentiment_df = generate_sentiment_data(start_date, end_date)
    policy_df, policies = generate_policy_data(start_date, end_date)
    event_df, events = generate_event_data(start_date, end_date)
    
    # 生成或使用传入的汇率数据
    if exchange_rate_data is None:
        exchange_rate_df = generate_exchange_rate_data(sentiment_df, policy_df, event_df, start_date, end_date, currency_pair)
    else:
        exchange_rate_df = exchange_rate_data
    
    # 分析影响
    combined_df = analyze_impacts(exchange_rate_df, sentiment_df, policy_df, event_df)
    
    # 如果有预测数据，添加到DataFrame
    if predicted_rate is not None:
        combined_df['predicted_rate'] = predicted_rate
    
    # 分析各因素贡献度
    analysis_results = analyze_factor_contribution(combined_df)
    print(f"舆论情绪贡献度: {analysis_results['sentiment_contrib']:.2%}")
    print(f"政策影响贡献度: {analysis_results['policy_contrib']:.2%}")
    print(f"事件影响贡献度: {analysis_results['event_contrib']:.2%}")
    print(f"模型拟合优度(R²): {analysis_results['r2']:.4f}")
    
    # 可视化结果
    visualize_results(combined_df, policies, events, currency_pair, analysis_results)
    
    print(f"{currency_pair}汇率影响因素分析完成，请查看output_images目录中的图表文件。")
    
    # 返回分析结果和数据
    return {
        'combined_df': combined_df,
        'policy_events': policies,
        'major_events': events,
        'analysis_results': analysis_results
    }

if __name__ == "__main__":
    main()